package aip.ui.user.srvc;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.ListOrderedMap;
import org.springframework.util.StringUtils;

import aip.core.dao.information.CatalogDao;
import aip.core.dao.user.CompanyDao;
import aip.core.dao.user.ExpertDao;
import aip.core.dao.user.UserDao;
import aip.core.model.information.Catalog;
import aip.core.model.user.User;
import aip.core.mvc.pageController.PageController;
import aip.ui.user.util.UserHelper;
import aip.ui.user.web.spring.UserEditForm;
import aip.ui.user.web.spring.UserListForm;

import com.googlecode.horncomb.bean.paged.PagedList;
import com.googlecode.horncomb.bean.paged.PagedSetting;

/**
 * User form service
 * <p>
 * 负责人/principal:<br/>
 * 修改记录/revision:<br/>
 * 日期:<br/>
 * 修改人:<br/>
 * 修改说明:<br/>
 * @author
 * @version $Id$
 */
public class UserFormService
{
    private UserDao userDao;
    private ExpertDao expertDao;
    private CompanyDao companyDao;
    private CatalogDao catalogDao;

    /** 用户类型：管理员、专家用户、网站用户 */
    private ListOrderedMap userTypeRefer = new ListOrderedMap();
    /** 状态：待审核、审核通过、审核退回 */
    private ListOrderedMap userStateRefer = new ListOrderedMap();

    /** 所属行业 */
    private ListOrderedMap companyDomainRefer = new ListOrderedMap();
    /** 企业规模 */
    private ListOrderedMap companySizeRefer = new ListOrderedMap();
    /** 网络建设情况 */
    private ListOrderedMap companyNetStatusRefer = new ListOrderedMap();
    /** 专有系统建设情况 */
    private ListOrderedMap companySystemStatusRefer = new ListOrderedMap();
    /** 拥有自有IT队伍 */
    private ListOrderedMap companyItGroupSizeRefer = new ListOrderedMap();

    /** 专家领域 */
    private ListOrderedMap expertDomainRefer = new ListOrderedMap();

    /**
     * @param expertDomainRefer
     *        the expertDomainRefer to set
     */
    public void setExpertDomainRefer(ListOrderedMap expertDomainRefer)
    {
        this.expertDomainRefer = expertDomainRefer;
    }

    /**
     * User列表
     * @param form
     *        表单对象
     * @return 列表页面数据
     * @throws Exception
     */
    public Map<String, Object> listReference(UserListForm form)
            throws Exception
    {
        Map<String, Object> ref = new HashMap<String, Object>();
        PagedSetting ps = form.getPagedSettingMap().values().iterator().next();
        PagedList<List<? extends User>> result = this.userDao.query(ps
                .getConditionSet(), ps.getOrder(), ps.getPage(), ps
                .getPageSize());
        ref.put("userList", result.getSource()); //$NON-NLS-1$
        ref.put("totalRows", result.getNrOfElements()); //$NON-NLS-1$
        this.publishConfig(ref);
        return ref;
    }

    /**
     * 删除选中的项
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void deleteItems(UserListForm form) throws Exception
    {
        if (form.getSelectedIds().size() > 0)
        {
            this.userDao.deleteByUsernames(form.getSelectedIds());
            this.expertDao.deleteByUsernames(form.getSelectedIds());
            this.companyDao.deleteByUsernames(form.getSelectedIds());
        }
    }

    public Map<String, Object> validUserExsit(UserEditForm form)
    {
        // other reference data
        Map<String, Object> ref = new HashMap<String, Object>();
        if (this.userDao.getById(form.getUsername()) != null)
        {
            ref.put("userExist", true);
        }
        else
        {
            ref.put("userExist", false);
        }
        return ref;

    }

    public Map<String, Object> getSubExpertDomain(UserEditForm form)
    {
        // other reference data
        Map<String, Object> ref = new HashMap<String, Object>();
        Catalog catalog = this.catalogDao.getCatalogMap()
                .get(form.getCatalog());
        List<Catalog> subCatalogList = new ArrayList<Catalog>();
        if (catalog.getChildren().size() == 0)
        {
            subCatalogList.add(catalog);
        }
        else
        {
            subCatalogList.addAll(catalog.getChildren().values());
        }
        ref.put("subCatalogList", subCatalogList);
        return ref;

    }

    /**
     * 获得User表单主对象
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void get(UserEditForm form) throws Exception
    {
        if (form != null && StringUtils.hasText(form.getUser().getUsername()))
        {
            User user = this.userDao.getById(form.getUser().getUsername());
            if (user != null)
            {
                form.setUser(user);
                if ("company".equals(user.getType()))
                {
                    form
                            .setCompany(this.companyDao.getById(user
                                    .getUsername()));
                }
                else if ("expert".equals(user.getType()))
                {
                    form.setExpert(this.expertDao.getById(user.getUsername()));
                }
                else if ("admin".equals(user.getType()))
                {
                }
            }
        }
    }

    /**
     * 获得User表单主对象
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void getUserInfo(UserEditForm form) throws Exception
    {
        User user = UserHelper.getUser();
        form.setUser(user);
        if ("company".equals(user.getType()))
        {
            form.setCompany(this.companyDao.getById(user.getUsername()));
        }
        else if ("expert".equals(user.getType()))
        {
            form.setExpert(this.expertDao.getById(user.getUsername()));
        }
    }

    /**
     * 显示编辑User界面相关数据
     * @param form
     *        表单对象
     * @return 显示页面数据
     * @throws Exception
     */
    public Map<String, Object> showReference(UserEditForm form)
            throws Exception
    {
        // other reference data
        Map<String, Object> ref = new HashMap<String, Object>();
        this.publishConfig(ref);
        form.getExpert().getDomainSet();
        form.getExpert().getDomain();
        ref.put("catalogMap", this.catalogDao.getCatalogMap());
        return ref;
    }

    /**
     * 注册信息
     * @param form
     * @return
     * @throws Exception
     */
    public Map<String, Object> registerReference(UserEditForm form)
            throws Exception
    {
        Map<String, Object> ref = this.showReference(form);
        form.getUser().setType("company");
        ref.put("isRegister", true);
        return ref;
    }

    /**
     * 提交注册
     * @param form
     * @throws Exception
     */
    public void saveSubmitRegister(UserEditForm form) throws Exception
    {
        form.getUser().setState(0);
        form.getUser().setType("company");
        this.save(form);
    }

    private void publishConfig(Map<String, Object> ref)
    {
        ref.put("userTypeRefer", this.userTypeRefer);
        ref.put("userTypeReferList", this.userTypeRefer.keyList());

        ref.put("userStateRefer", this.userStateRefer);
        ref.put("userStateReferList", this.userStateRefer.keyList());

        ref.put("companyDomainRefer", this.companyDomainRefer);
        ref.put("companyDomainReferList", this.companyDomainRefer.keyList());

        ref.put("companySizeRefer", this.companySizeRefer);
        ref.put("companySizeReferList", this.companySizeRefer.keyList());

        ref.put("companyNetStatusRefer", this.companyNetStatusRefer);
        ref.put("companyNetStatusReferList", this.companyNetStatusRefer
                .keyList());

        ref.put("companyItGroupSizeRefer", this.companyItGroupSizeRefer);
        ref.put("companyItGroupSizeReferList", this.companyItGroupSizeRefer
                .keyList());

        ref.put("companySystemStatusRefer", this.companySystemStatusRefer);
        ref.put("companySystemStatusReferList", this.companySystemStatusRefer
                .keyList());

        ref.put("expertDomainRefer", this.expertDomainRefer);
        ref.put("expertDomainReferList", this.expertDomainRefer.keyList());

        ref.put("expertDomainRefer", this.catalogDao.getCatalogMap());
        ref.put("expertDomainReferList", this.catalogDao.getCatalogMap()
                .keySet());

        ref.put("allCatalogMap", this.catalogDao.getAllCatalog());

    }

    /**
     * 保存User表单
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void save(UserEditForm form) throws Exception
    {
        if (StringUtils.hasText(form.getPassword()))
        {
            // 有修改密码
            form.getUser().setPassword(
                    this.userDao.encodePassword(form.getPassword()));
        }
        if (!StringUtils.hasText(form.getUser().getUsername()))
        {
            form.getUser().setCreate(new Date());
            form.getUser().setUsername(form.getUsername().toUpperCase());
            this.userDao.insert(form.getUser());
            if ("company".equals(form.getUser().getType()))
            {
                form.getCompany().setUsername(form.getUsername().toUpperCase());
                this.companyDao.insert(form.getCompany());
            }
            else if ("expert".equals(form.getUser().getType()))
            {
                form.getExpert().setUsername(form.getUsername().toUpperCase());
                this.expertDao.insert(form.getExpert());
            }
        }
        else
        {
            form.getUser().setModify(new Date());
            this.userDao.update(form.getUser());
            if ("company".equals(form.getUser().getType()))
            {
                form.getCompany().setUsername(form.getUser().getUsername());
                this.companyDao.update(form.getCompany());
                this.expertDao.deleteById(form.getUser().getUsername());
            }
            else if ("expert".equals(form.getUser().getType()))
            {
                form.getExpert().setUsername(form.getUser().getUsername());
                this.expertDao.update(form.getExpert());
                this.companyDao.deleteById(form.getUser().getUsername());
            }
            else
            {
                this.expertDao.deleteById(form.getUser().getUsername());
                this.companyDao.deleteById(form.getUser().getUsername());
            }
        }
    }

    /**
     * 删除单个User
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void deleteItem(UserListForm form) throws Exception
    {
        this.userDao.deleteByUsername(form.getUser().getUsername());
        this.expertDao.deleteByUsername(form.getUser().getUsername());
        this.companyDao.deleteByUsername(form.getUser().getUsername());
    }

    /**
     * 用户审核
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void updateStateByItems(UserListForm form) throws Exception
    {
        this.userDao.updateStateByItems(form.getSelectedIds(), form.getState());
    }

    /**
     * 专家信息展现
     * @param form
     * @return
     * @throws Exception
     */
    public Map<String, Object> expertInfoList(UserListForm form)
            throws Exception
    {
        Map<String, Object> ref = new HashMap<String, Object>();
        String type = "expert";
        List<? extends User> userList = this.userDao.queryListByType(type, form
                .getLikeDomain(), form.getStart() + 1, 20);
        ref.put("userList", userList);
        String url = "../user/expertInfoList.shtml";
        // 分页
        if (userList.size() > 0)
        {
            PageController pc = new PageController();
            pc.setPageSize(20);
            pc.setRowCount(this.userDao
                    .getDataCount(type, form.getLikeDomain()));
            pc.setShowPage(form.getStart());
            pc.setUrl(url);
            pc.setShowPageEnum(new Boolean(true));
            pc.setDivClassName("page");
            pc.setShowInput(new Boolean(true));
            pc.setShowPageEnumCount(5);
            pc.setButtonClassName("pageGoButton");
            pc.setInputClassName("pageInput");
            ref.put("pageStr", pc.getPageController());
        }
        ref.put("catalogMap", this.catalogDao.getCatalogMap());
        return ref;
    }

    /**
     * @param userDao
     *        the userDao to set
     */
    public void setUserDao(UserDao userDao)
    {
        this.userDao = userDao;
    }

    /**
     * @param expertDao
     *        the expertDao to set
     */
    public void setExpertDao(ExpertDao expertDao)
    {
        this.expertDao = expertDao;
    }

    /**
     * @param companyDao
     *        the companyDao to set
     */
    public void setCompanyDao(CompanyDao companyDao)
    {
        this.companyDao = companyDao;
    }

    public ListOrderedMap getUserTypeRefer()
    {
        return userTypeRefer;
    }

    /**
     * @param userTypeRefer
     *        the userTypeRefer to set
     */
    public void setUserTypeRefer(ListOrderedMap userType)
    {
        this.userTypeRefer = userType;
    }

    /**
     * @param userStateRefer
     *        the userStateRefer to set
     */
    public void setUserStateRefer(ListOrderedMap userState)
    {
        this.userStateRefer = userState;
    }

    /**
     * @param companyDomainRefer
     *        the companyDomainRefer to set
     */
    public void setCompanyDomainRefer(ListOrderedMap companyDomain)
    {
        this.companyDomainRefer = companyDomain;
    }

    /**
     * @param companySizeRefer
     *        the companySizeRefer to set
     */
    public void setCompanySizeRefer(ListOrderedMap companySize)
    {
        this.companySizeRefer = companySize;
    }

    /**
     * @param companyNetStatusRefer
     *        the companyNetStatusRefer to set
     */
    public void setCompanyNetStatusRefer(ListOrderedMap companyNetStatus)
    {
        this.companyNetStatusRefer = companyNetStatus;
    }

    /**
     * @param companySystemStatusRefer
     *        the companySystemStatusRefer to set
     */
    public void setCompanySystemStatusRefer(ListOrderedMap companySystemStatus)
    {
        this.companySystemStatusRefer = companySystemStatus;
    }

    /**
     * @param companyItGroupSizeRefer
     *        the companyItGroupSizeRefer to set
     */
    public void setCompanyItGroupSizeRefer(ListOrderedMap companyItGroupSize)
    {
        this.companyItGroupSizeRefer = companyItGroupSize;
    }

    /**
     * @return the companyItGroupSizeRefer
     */
    public ListOrderedMap getCompanyItGroupSizeRefer()
    {
        return companyItGroupSizeRefer;
    }

    /**
     * @param catalogDao
     *        the catalogDao to set
     */
    public void setCatalogDao(CatalogDao catalogDao)
    {
        this.catalogDao = catalogDao;
    }
}
